package handler

import (
	"fitness/go-admin/internal/model"
	"fitness/go-admin/internal/service"
	"fitness/go-admin/pkg/cache"
	"fitness/go-admin/pkg/errcode"
	"fitness/go-admin/pkg/logger"
	"fitness/go-admin/pkg/response"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
)

type AuthHandler struct {
	service service.AuthService
}

func NewAuthHandler(service service.AuthService) *AuthHandler {
	return &AuthHandler{service: service}
}

// Register 用户注册
// @Summary 用户注册
// @Tags 认证
// @Accept json
// @Produce json
// @Param body body model.RegisterReq true "注册信息"
// @Success 200 {object} response.Response
// @Router /auth/register [post]
func (h *AuthHandler) Register(c *gin.Context) {
	var req model.RegisterReq
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, errcode.BadRequest, "参数错误: "+err.Error())
		return
	}

	if err := h.service.Register(&req); err != nil {
		logger.Warn("用户注册失败", "username", req.Username, "error", err.Error(), "ip", c.ClientIP())
		response.Error(c, errcode.BadRequest, err.Error())
		return
	}

	// 记录审计日志
	logger.LogAudit(logger.AuditLog{
		Username:  req.Username,
		Action:    "REGISTER",
		Resource:  "user",
		IP:        c.ClientIP(),
		UserAgent: c.GetHeader("User-Agent"),
	})

	response.Success(c, nil, "注册成功")
}

// Login 用户登录
// @Summary 用户登录
// @Tags 认证
// @Accept json
// @Produce json
// @Param body body model.LoginReq true "登录信息"
// @Success 200 {object} response.Response{data=model.LoginResp}
// @Router /auth/login [post]
func (h *AuthHandler) Login(c *gin.Context) {
	var req model.LoginReq
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, errcode.BadRequest, "参数错误: "+err.Error())
		return
	}

	resp, err := h.service.Login(&req)
	if err != nil {
		logger.Warn("用户登录失败", "username", req.Username, "error", err.Error(), "ip", c.ClientIP())
		response.Error(c, errcode.InvalidCredentials, err.Error())
		return
	}

	// 记录审计日志
	logger.LogAudit(logger.AuditLog{
		UserID:    resp.User.ID,
		Username:  resp.User.Username,
		Action:    "LOGIN",
		Resource:  "user",
		IP:        c.ClientIP(),
		UserAgent: c.GetHeader("User-Agent"),
	})

	response.Success(c, resp, "登录成功")
}

// GetUserInfo 获取当前用户信息
// @Summary 获取用户信息
// @Tags 认证
// @Produce json
// @Success 200 {object} response.Response{data=model.UserInfo}
// @Router /auth/userinfo [get]
func (h *AuthHandler) GetUserInfo(c *gin.Context) {
	userID, exists := c.Get("userId")
	if !exists {
		response.Error(c, 401, "未登录")
		return
	}

	info, err := h.service.GetUserInfo(userID.(uint))
	if err != nil {
		response.Error(c, 500, err.Error())
		return
	}

	response.Success(c, info, "获取成功")
}

// ChangePassword 修改密码
// @Summary 修改密码
// @Tags 认证
// @Accept json
// @Produce json
// @Param body body model.ChangePasswordReq true "密码信息"
// @Success 200 {object} response.Response
// @Router /auth/change-password [post]
func (h *AuthHandler) ChangePassword(c *gin.Context) {
	userID, exists := c.Get("userId")
	if !exists {
		response.Error(c, errcode.Unauthorized, "")
		return
	}

	var req model.ChangePasswordReq
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, errcode.BadRequest, "参数错误: "+err.Error())
		return
	}

	if err := h.service.ChangePassword(userID.(uint), &req); err != nil {
		response.Error(c, errcode.BadRequest, err.Error())
		return
	}

	// 记录审计日志
	logger.LogAudit(logger.AuditLog{
		UserID:    userID.(uint),
		Action:    "CHANGE_PASSWORD",
		Resource:  "user",
		IP:        c.ClientIP(),
		UserAgent: c.GetHeader("User-Agent"),
	})

	response.Success(c, nil, "密码修改成功")
}

// UpdateProfile 更新个人资料
// @Summary 更新个人资料
// @Tags 认证
// @Accept json
// @Produce json
// @Param body body model.UpdateProfileReq true "个人资料"
// @Success 200 {object} response.Response
// @Router /auth/profile [put]
func (h *AuthHandler) UpdateProfile(c *gin.Context) {
	userID, exists := c.Get("userId")
	if !exists {
		response.Error(c, 401, "未登录")
		return
	}

	var req model.UpdateProfileReq
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误: "+err.Error())
		return
	}

	if err := h.service.UpdateProfile(userID.(uint), &req); err != nil {
		response.Error(c, 500, err.Error())
		return
	}

	response.Success(c, nil, "更新成功")
}

// Logout 退出登录
// @Summary 退出登录
// @Tags 认证
// @Produce json
// @Success 200 {object} response.Response
// @Router /auth/logout [post]
func (h *AuthHandler) Logout(c *gin.Context) {
	// 将Token加入黑名单
	authHeader := c.GetHeader("Authorization")
	if authHeader != "" && cache.RedisClient != nil {
		parts := strings.SplitN(authHeader, " ", 2)
		if len(parts) == 2 && parts[0] == "Bearer" {
			token := parts[1]
			// Token过期时间设为2小时（与AccessToken一致）
			_ = cache.AddToBlacklist(token, 2*time.Hour)
		}
	}

	response.Success(c, nil, "退出成功")
}

// RefreshToken 刷新访问令牌
// @Summary 刷新Token
// @Tags 认证
// @Accept json
// @Produce json
// @Param body body model.RefreshTokenReq true "RefreshToken"
// @Success 200 {object} response.Response{data=model.RefreshTokenResp}
// @Router /auth/refresh-token [post]
func (h *AuthHandler) RefreshToken(c *gin.Context) {
	var req model.RefreshTokenReq
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误: "+err.Error())
		return
	}

	resp, err := h.service.RefreshToken(&req)
	if err != nil {
		response.Error(c, 401, err.Error())
		return
	}

	response.Success(c, resp, "刷新成功")
}
